"""Debug 日志解析"""
import json
import json_repair
import re
from typing import List, Dict
import hashlib
from pathlib import Path


class LogParser(object):

    def __init__(self, log_file):
        with open(log_file, 'r', encoding='utf-8') as fs:
            self.lines = fs.readlines()

    @staticmethod
    def hash(data):
        sha256_hash = hashlib.new('sha256')
        sha256_hash.update(json.dumps(data, ensure_ascii=False).encode('utf-8'))
        hash_value = sha256_hash.hexdigest()
        return hash_value

    def get_input_datas(self)->List:
        input_datas = dict()
        for idx, line in enumerate(self.lines):
            if line.find('传入数据:') == -1:
                continue
            input_data = json_repair.repair_json(line, return_objects=True)
            key = self.hash(input_data)
            input_datas[key] = input_data
        return list(input_datas.values())

    @staticmethod
    def find_data_by_id(input_datas: List, file_id: str)-> Dict:
        for input_data in input_datas:
            if file_id == input_data['fileId']:
                return input_data
        return {}

    @staticmethod
    def find_data_by_name(input_datas: List, file_name: str)-> Dict:
        for input_data in input_datas:
            if file_name == input_data['documentName']:
                return input_data
        return {}

    def get_block_contents(self, input_data: Dict) -> List:
        """获取合同分块的日志"""

        # 第一步：先找到传入当前数据的地方
        start_idx = 0
        hash_value = self.hash(input_data)
        for idx, line in enumerate(self.lines):
            if line.find('传入数据:') == -1:
                continue
            data = json_repair.repair_json(line, return_objects=True)
            if hash_value == self.hash(data):
                start_idx = idx
                break

        # 第二步：传入数据之后的日志是分块数据
        blocks = []
        for idx, line in enumerate(self.lines):
            if idx <= start_idx:
                continue
            if line.find("{'content':") != -1:
                data = json_repair.repair_json(line, return_objects=True)
                blocks.append(data)
            if line.find('合同入库完成: ') != -1:
                break
        return blocks

    def get_extracts(self, input_data) -> List:
        """获取input_data 对应的 要素抽取日志"""
        extracts = dict()
        file_id = input_data['fileId']
        started = False
        recalls = None
        texts = None
        for idx, line in enumerate(self.lines):
            if line.find('要素内容抽取') != -1 and line.find(f'"fileId": "{file_id}"') != -1:
                started = True
                recalls = []
                texts = []
                continue

            # 召回
            if started and line.find('content=') != -1 and line.find('distance=') != -1:
                recalls.append(re.search('(content=.*)\s*distance=',line).group(1))
                continue

            # prompt
            if started and re.search('(\| DEBUG    \|)|(\| INFO     \|)|(\| ERROR    \|)', line) is None:
                texts.append(line)
                continue

            if started and line.find('要素抽取结果:') != -1:
                started = False
                data = dict()
                data['recalls'] = '\n'.join(recalls)
                data['prompt'] = ''.join(texts).strip()
                result = json_repair.repair_json(line, return_objects=True)
                data.update(result)
                key = result['id']
                extracts[key] = data
                continue
        return list(extracts.values())

    def get_reviews(self, input_data) -> List:
        """获取input_data 对应的 语义审查日志"""
        reviews = dict()
        started = False
        recalls = None
        texts = None
        file_id = input_data['fileId']

        for idx, line in enumerate(self.lines):
            if line.find('要素语义审查:') != -1 and line.find(f'"fileId": "{file_id}"') != -1:
                started = True
                recalls = []
                texts = []
                continue

            # 召回
            if started and line.find('content=') != -1 and line.find('distance=') != -1:
                recalls.append(re.search('(content=.*)\s*distance=',line).group(1))
                continue

            # prompt
            if started and re.search('(\| DEBUG    \|)|(\| INFO     \|)|(\| ERROR    \|)', line) is None:
                texts.append(line)
                continue

            if started and line.find('语义审查结果:') != -1:
                started = False
                data = dict()
                data['recalls'] = '\n'.join(recalls)
                data['prompt'] = ''.join(texts).strip()
                result = json_repair.repair_json(line, return_objects=True)
                data.update(result)
                key = result['id']
                reviews[key] = data
                continue
        return list(reviews.values())


if __name__ == '__main__':

    log_file = Path(__file__).parent.parent / 'logs' / 'debug.log'
    parser = LogParser(log_file)

    # 获取输入数据
    input_datas = parser.get_input_datas()
    # input_data = parser.find_data_by_id(input_datas, file_id="f68c60eda6c75443d8040d655b85bc34f")
    input_data = parser.find_data_by_name(input_datas, file_name="#  40.5T-45M轨道式集装箱龙门起重机转让协议.docx")

    # 获取分块内容
    contents = parser.get_block_contents(input_data)

    # 获取要素抽取的日志
    extracts = parser.get_extracts(input_data)

    # 获取语义审查的日志
    review_inputs = parser.get_reviews(input_data)
